/*
 * master_service.c
 *
 *  Created on: Jan 5, 2013
 *      Author: duoln
 */
#include <stdlib.h>
#include <stdio.h>
#include <lfs.h>
#include <logging.h>
#include <map.h>
#include <emalloc.h>
#include <master_service.h>
#include <master_manager.h>
#include <lfs_protocol.h>

typedef struct
{
    Map* mDispatcher;
} MasterHandler;

static Logger* mLog = NULL;

static MasterHandler* mHandler = NULL;

void master_service_init()
{
    mLog = GET_LOGGER("/lfs/masterserver");
    mHandler = emalloc(sizeof(MasterHandler));
    mHandler->mDispatcher = map_new(MAP_STRING);

    map_put(mHandler->mDispatcher, MASTER_HANDLER_FILE_META, master_service_file_meta);
    map_put(mHandler->mDispatcher, MASTER_HANDLER_FILE_CREATE, master_service_file_create);
    map_put(mHandler->mDispatcher, MASTER_HANDLER_FILE_WRITE, master_service_file_write);
    map_put(mHandler->mDispatcher, MASTER_HANDLER_FILE_DELETE, master_service_file_delete);
    map_put(mHandler->mDispatcher, MASTER_HANDLER_FILE_META_UPDATE, master_service_file_meta_update);

    master_manager_init();
}

void master_service_request(Request* req, Response* resp)
{
    HandlerFunc func;
    char* method = req->method;

    if (!map_get(mHandler->mDispatcher, (void*) method, (void*) &func))
    {
        logger(FATAL(mLog), "Method '%s' is not exist");
        resp->status = RPC_FAIL;
        resp->size = 0;
        resp->data = NULL;
    }
    else
    {
        void* input = NULL, *output = NULL;//protocol object

        Buffer* req_buf = buffer_new_1(req->size);
        buffer_write(req_buf,req->data, req->size);

        //stream to object
        buffer_reset(req_buf);
        lfs_protocol_deserialize(method, req_buf, NULL, &input, &output);

        //handler
        func(input, output);

        //object to stream
        Buffer* resp_buf = buffer_new();;
        lfs_protocol_serialize(method, NULL, output, NULL, resp_buf);

        resp->status = RPC_SUCC;
        resp->size = buffer_get_size(resp_buf);
        resp->data = buffer_get_data(resp_buf);
    }
}

void master_service_file_create(void* input, void* output)
{
    FileCreateRequest* request = (FileCreateRequest*) input;
    FileCreateResponse* response = (FileCreateResponse*) output;
    Status ret = master_manager_file_create(request->filename, request->min_replica, request->max_replica);
    response->status = ret;
}

void master_service_file_write(void* input, void* output)
{
    FileWriteRequest* request = (FileWriteRequest*) input;
    FileWriteRespoonse* response = (FileWriteRespoonse*) output;
    int64_t* id = NULL;
    Status ret = master_manager_file_write(request->filename, request->size, &id);
    response->id = *id;
    response->status = ret;
}

void master_service_file_meta(void* input, void* output)
{
}

void master_service_file_delete(void* input, void* output)
{
}

void master_service_file_meta_update(void* input, void* output)
{
}

void master_service_no_method(void* input, void* output)
{
}

